using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEditor;
using UnityEngine;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using LitJson;


public class AdsKitBuildProcessor : IPostprocessBuildWithReport
{
    public int callbackOrder
    {
        get { return 10; }
    }

    /**
    * build 构建完成后回调
    */
    public void OnPostprocessBuild(BuildReport report)
    {
        if (report.summary.platform == BuildTarget.OpenHarmony)
        {
            Debug.Log("Path is :" + report.summary.outputPath);
            CustomRecodeFile(report.summary.outputPath);
        }
    }

    private void CustomRecodeFile(string path)
    {
        ModifyMainWorker(path);
        ModifyModuleJson5(path);
    }


    /**
     * TuanjieMainWorker.cs 新增import和消息监听代码
     */
    private void ModifyMainWorker(string path)
    {
        string filePath = path + "/tuanjieLib/src/main/ets/workers/WorkerProxy.ets";
        if (!File.Exists(filePath)) return;
        FileOperator foOhPackage = new FileOperator(filePath);
        // 增加import内容
        var importLine = "import { SDKManager } from '../entry/handler/SDKManager';";
        foOhPackage.InsertImports(importLine);
 
        // 在onmessage方法后面插入SDKManager.InitMessageBind
        var insertCode = "    SDKManager.InitMessageBind(this.threadWorker);";
        string afterFunction = "this.threadWorker.onmessage = (msg) =>";
        bool findAnchor = false;
        bool findInsertPos = false;
        int bracesCount = 0;
        string[] codes = File.ReadAllLines(filePath);
        if (codes.Length == 0 || Array.Exists(codes, line => line.Contains(insertCode))) return;
        string[] codesNew = new string[codes.Length + 1];
        int index;
        for (index = 0; index < codes.Length; index++)
        {
            if (!findInsertPos)
            {
                codesNew[index] = codes[index];
            }
            else
            {
                codesNew[index] = insertCode;
                break;
            }

            if (findAnchor)
            {
                bracesCount += CountSymbolInLine('{', codes[index]);
                bracesCount -= CountSymbolInLine('}', codes[index]);

                if (bracesCount == 0)
                {
                    findInsertPos = true;
                    findAnchor = false;
                }

                continue;
            }

            // 找到方法入口，开始计数大括号，直到方法结束
            if (codes[index].Contains(afterFunction))
            {
                findAnchor = true;
                if (codes[index].Contains("{")) bracesCount++;
            }
        }

        for (int i = index + 1; i < codes.Length + 1; i++)
        {
            codesNew[i] = codes[i - 1];
        }

        File.WriteAllLines(filePath, codesNew);
    }

    private int CountSymbolInLine(char symbol, string lineContent)
    {
        IEnumerable<char> stringQuery =
            from ch in lineContent
            where ch.Equals(symbol)
            select ch;
        return stringQuery.Count();
    }

    /**
     * module.json5 修改appId/clientId，可在HMSSetting中修改
     */
    private void ModifyModuleJson5(string path)
    {
        // HMSBuildSettingItem item = AssetDatabase.LoadAssetAtPath<HMSBuildSettingItem>(HMSBuildSetting.settingFilePath);
        string moduleJson5FilePath = path + "/entry/src/main/module.json5";
        string jsonIn = File.ReadAllText(moduleJson5FilePath);
        JsonData jsonData = JsonMapper.ToObject(jsonIn);
        JsonData metadataList = jsonData["module"]["metadata"];
        JsonData appIdDataObj = new JsonData();
        appIdDataObj.SetJsonType(JsonType.Object);

        // 添加app_tracking_consent权限，用于获取OAID，不接入广告时可以删除
        JsonData requestPermissionsList = jsonData["module"]["requestPermissions"];
        JsonData appTrackingDataObj = DefaultPermissionJsonData();
        appTrackingDataObj["name"] = "ohos.permission.APP_TRACKING_CONSENT";
        requestPermissionsList.Add(appTrackingDataObj);

        string jsonOut = JsonMapper.ToJson(jsonData);
        File.WriteAllText(moduleJson5FilePath, jsonOut);
    }

    private JsonData DefaultPermissionJsonData()
    {
        JsonData UsedSceneData = new JsonData();
        UsedSceneData.SetJsonType(JsonType.Object);
        UsedSceneData["abilities"] = new JsonData();
        UsedSceneData["abilities"].Add(0);
        UsedSceneData["abilities"][0] = "TuanjiePlayerAbility";
        UsedSceneData["when"] = "inuse";
        JsonData DefaultPermission = new JsonData();
        DefaultPermission.SetJsonType(JsonType.Object);
        DefaultPermission["name"] = "";
        DefaultPermission["usedScene"] = UsedSceneData;
        DefaultPermission["reason"] = "$string:default_reason";

        return DefaultPermission;
    }
}